package com.zengqingfa.examples.mybatisplus.util;

import com.zengqingfa.examples.mybatisplus.annotation.LogCompare;
import com.zengqingfa.examples.mybatisplus.entity.BaseLog;
import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @fileName: CompareUtil
 * @author: zengqf3
 * @date: 2021-4-6 11:29
 * @description:
 */
public class CompareUtil {

    /**
     * 比较两个对象的差别
     * @param oldObj
     * @param newObj
     * @return
     * @throws IllegalAccessException
     */
    public static BaseLog comparatorObject(Object oldObj, Object newObj) throws IllegalAccessException {
        BaseLog baseLog = new BaseLog();
        StringBuilder field = new StringBuilder();
        StringBuilder fieldValue = new StringBuilder();
        Map<String, Object> oldMap = changeValueToMap(oldObj);
        Map<String, Object> newMap = changeValueToMap(newObj);
        if (oldMap != null && !oldMap.isEmpty()) {
            for (Map.Entry<String, Object> entry : oldMap.entrySet()) {
                Object oldValue = entry.getValue();
                Object newValue = newMap.get(entry.getKey());
                if (!oldValue.equals(newValue)) {
                    field.append(entry.getKey()).append("|");
                    fieldValue.append(oldValue).append("->").append(newValue).append("|");
                }
            }
        }
        baseLog.setUpdateField(field.toString());
        baseLog.setUpdateFieldValue(fieldValue.toString());
        return baseLog;
    }

    /**
     * 将类对象转换成Map
     *
     * @param entity 原对象
     * @return Map
     * @throws IllegalAccessException 类型转换时报错
     */
    public static Map<String, Object> changeValueToMap(Object entity) throws IllegalAccessException {
        Map<String, Object> resultMap = new HashMap<>(16);
        Field[] fields = entity.getClass().getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            if (PropertyUtils.isReadable(entity, name) && PropertyUtils.isWriteable(entity, name)) {
                if (field.isAnnotationPresent(LogCompare.class)) {
                    LogCompare annotation = field.getAnnotation(LogCompare.class);
                    //获取private对象字段值
                    field.setAccessible(true);
                    resultMap.put(annotation.name(), field.get(entity));
                }
            }
        }
        return resultMap;
    }
}
